package com.zhuoyue.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zhuoyue.biz.core.api.service.impl.DeviceService;
import com.zhuoyue.common.aop.auth.CheckLogin;

import com.zhuoyue.biz.core.api.dao.DeviceDao;
import com.zhuoyue.biz.core.api.domain.DeviceAndGatewayDO;
import com.zhuoyue.biz.core.api.domain.DeviceDO;
import com.zhuoyue.biz.core.api.domain.GatewayDO;
import com.zhuoyue.biz.core.api.domain.TblZigbeeDeviceLinkageRelation;
import com.zhuoyue.biz.core.api.dto.rep.GroupRepDTO;
import com.zhuoyue.biz.core.api.service.*;
import com.zhuoyue.biz.core.command.cmd.common.faa.MultiFunctionSwitch0Faa8A09;
import com.zhuoyue.common.aop.auth.User;
import com.zhuoyue.common.dto.ControllerResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;
import java.util.List;


/**
 * @author hewenze
 * @ClassName: 联动绑定配置
 * @Description:
 * @Date 2021/4/16 13:36
 */
@RestController
@RequestMapping("/api/linkage")
@Validated
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AppLinkageSetController {

    private final GatewayRedisService gatewayRedisService;

    private final TblZigbeeDeviceLinkageRelationService linkageRelationService;

    private final DeviceService deviceService;

    private final GroupService groupService;

    private final GatewayService gatewayService;

    private final DeviceDao deviceDao;

    private static final String DEVICE = "device";
    private static final String GROUP = "group";


    /**
     * 获取联动绑定关系列表(新参数)
     *
     * @param startDeviceMac   设备ID
     * @param startProductType 设备way
     * @param gatewayId        网关ID
     * @return
     */
    @GetMapping("/list")
    @CheckLogin
    public ControllerResult getLinkageListStartDeviceId(String startDeviceMac, String startProductType, String gatewayId, HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [getLinkageListStartDeviceId] -> [startDeviceMac:{},startProductType:{},gatewayId:{}]",
                user.getAccount(), user.getOrgCode(), startDeviceMac, startProductType, gatewayId);

        QueryWrapper<DeviceDO> deviceQuery = new QueryWrapper();
        deviceQuery.eq("zigbee_mac", startDeviceMac);
        deviceQuery.eq("product_type", startProductType);
        DeviceDO device = deviceService.getOne(deviceQuery);
        if (device != null) {
            QueryWrapper<TblZigbeeDeviceLinkageRelation> queryWrapper = new QueryWrapper();
            queryWrapper.eq("start_device_mac", startDeviceMac);
            queryWrapper.eq("start_product_type", startProductType);
            queryWrapper.eq("gateway_id", gatewayId);
            List<TblZigbeeDeviceLinkageRelation> list = linkageRelationService.list(queryWrapper);
            list.forEach(l -> {
                if (!l.getStartDeviceId().equals(device.getId())) {
                    linkageRelationService.removeById(l.getId());
                }
            });
            list = linkageRelationService.list(queryWrapper);
            if (list.size() > 0) {
                log.info("result ->  [getLinkageListStartDeviceId] -> [TblZigbeeDeviceLinkageRelationList:{}]", list);
                return ControllerResult.toReturnDataSuccess("获取成功", list);
            } else {
                return ControllerResult.toNoDataFail("无联动信息");
            }

        } else {
            return ControllerResult.toFail("设备不存在或已被删除");
        }

    }

    /***
     * 添加联动绑定关系
     * @param startDeviceId 开始设备ID
     * @param endId 结束设备或者群组的ID
     * @param endType 结束设备的类型
     * @param actions 结束设备的固定信息
     * @param mode 结束设备的模式(同步，切换，自定义)
     * @return
     */
    @PostMapping("/add")
    @CheckLogin
    public ControllerResult addLinkageRelation(@NotBlank(message = "添加联动关系信息") String startDeviceId,
                                               @NotBlank(message = "添加设备设备或群组的ID") String endId, String endType,
                                               String startSwitchState, String actions, String mode, HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [addLinkageRelation] -> [startDeviceId:{},endId:{},endType:{},startSwitchState:{},actions:{},mode:{}]",
                user.getAccount(), user.getOrgCode(), startDeviceId, endId, endType, startSwitchState, actions, mode);

        if (startDeviceId.equals(endId)) {
            return ControllerResult.toFail("同设备不可联动");
        }
        //如果源设备在表中有信息，且与表中网关id不一致，则删掉原数据，如果网关id一致，则无法添加
        DeviceDO startDevice = deviceService.getById(startDeviceId);
        QueryWrapper<TblZigbeeDeviceLinkageRelation> query = new QueryWrapper<>();
        query.eq("start_device_id", startDeviceId);
        query.eq("start_switch_state", startSwitchState);
        TblZigbeeDeviceLinkageRelation tblZigbeeDeviceLinkageRelationServiceOne = linkageRelationService.getOne(query);
        if (tblZigbeeDeviceLinkageRelationServiceOne != null) {
            if (startDevice.getGatewayId().equals(tblZigbeeDeviceLinkageRelationServiceOne.getGatewayId())) {
                return ControllerResult.toFail("此设备已有联动信息，无法添加");
            } else {
                //删除原数据
                boolean remove = linkageRelationService.remove(query);
                if (!remove) {
                    return ControllerResult.toFail("系统异常");
                }
            }
        }

        linkageRelationService.linkAgeSet(startDeviceId, endId, endType, startSwitchState, actions, mode, "add");
        TblZigbeeDeviceLinkageRelation linkageRelation = new TblZigbeeDeviceLinkageRelation();
        linkageRelation.setEndType(endType);
        linkageRelation.setMode(mode);
        linkageRelation.setActions(actions);
        linkageRelation.setStartSwitchState(startSwitchState);
        if (DEVICE.equals(endType)) {
            DeviceDO endDevice = deviceService.getById(endId);
            if (!startDevice.getGatewayId().equals(endDevice.getGatewayId())) {
                return ControllerResult.toFail("非同网关设备无法添加");
            }
            //结束设备mac
            linkageRelation.setEndDeviceMac(endDevice.getZigbeeMac());
            //结束设备类型
            linkageRelation.setEndDeviceType(endDevice.getDeviceType());
            //结束设备od
            linkageRelation.setEndOdIndex(endDevice.getOdIndex());
            //结束设备productType
            linkageRelation.setEndProductType(endDevice.getProductType());
        } else if (GROUP.equals(endType)) {
            GroupRepDTO groupRepDTO = groupService.selectGroupsDetailsById(endId);
            QueryWrapper<GatewayDO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("home_id", groupRepDTO.getHomeId());
            GatewayDO gatewayDO = gatewayService.getOne(queryWrapper);
            GatewayDO gatewayDo = gatewayService.getById(startDevice.getGatewayId());
            if (!gatewayDo.getZigbeeMac().equals(gatewayDO.getZigbeeMac())) {
                return ControllerResult.toFail("非同网关群组无法添加");
            }
            linkageRelation.setEndGroupId(groupRepDTO.getId());
        }
        linkageRelation.setStartDeviceId(startDeviceId);
        linkageRelation.setEndId(endId);
        linkageRelation.setGatewayId(startDevice.getGatewayId());
        linkageRelation.setStartDeviceMac(startDevice.getZigbeeMac());
        linkageRelation.setStartDeviceType(startDevice.getDeviceType());
        linkageRelation.setStartOdIndex(startDevice.getOdIndex());
        linkageRelation.setStartProductType(startDevice.getProductType());

        boolean save = linkageRelationService.save(linkageRelation);
        if (!save) {
            return ControllerResult.toFail("添加失败");
        }

        return ControllerResult.toReturnMessageSuccess("添加成功");
    }


    /**
     * 注意，结束设备信息直接是用来覆盖掉的
     *
     * @param id      需要修改的关系ID
     * @param endId   结束设备或者群组的ID
     * @param endType 结束设备的类型
     * @param actions 结束设备的固定信息
     * @param mode    结束设备的模式(同步，切换，自定义)
     * @return
     */
    @PutMapping("/update")
    @CheckLogin
    public ControllerResult getRoomListByHomeId(@NotBlank(message = "关系ID") String id, @NotBlank(message = "添加设备设备或群组的ID") String endId,
                                                String endType, String actions, String mode, HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [getRoomListByHomeId] -> [id:{},endId:{},endType:{},actions:{},mode:{}]",
                user.getAccount(), user.getOrgCode(), id, endId, endType, actions, mode);

        DeviceDO endDevice = new DeviceDO();
        GroupRepDTO groupRepDTO = new GroupRepDTO();
        if (DEVICE.equals(endType)) {
            DeviceDO endDevice1 = deviceService.getById(endId);
            if (endDevice1 == null) {
                return ControllerResult.toFail("设备不存在或已被删除");
            }
            endDevice = endDevice1;
        } else if (GROUP.equals(endType)) {
            GroupRepDTO groupRepDto = groupService.selectGroupsDetailsById(endId);
            if (groupRepDto == null) {
                return ControllerResult.toFail("群组不存在或已被删除");
            }
            groupRepDTO = groupRepDto;
        }
        TblZigbeeDeviceLinkageRelation tblZigbeeDeviceLinkageRelation = new TblZigbeeDeviceLinkageRelation();
        tblZigbeeDeviceLinkageRelation.setId(id);


        QueryWrapper<TblZigbeeDeviceLinkageRelation> queryWrapper = new QueryWrapper();
        queryWrapper.eq("id", id);
        TblZigbeeDeviceLinkageRelation deviceAndGatewayDo = linkageRelationService.getOne(queryWrapper);
        linkageRelationService.linkAgeSet(deviceAndGatewayDo.getStartDeviceId(), endId, endType, deviceAndGatewayDo.getStartSwitchState(), actions, mode, "update");
        
        //结束设备mac
        tblZigbeeDeviceLinkageRelation.setEndDeviceMac(endDevice.getZigbeeMac());
        if (DEVICE.equals(endType)) {
            //结束设备类型
            tblZigbeeDeviceLinkageRelation.setEndDeviceType(endDevice.getDeviceType());
            //结束设备od
            tblZigbeeDeviceLinkageRelation.setEndOdIndex(endDevice.getOdIndex());
            //结束设备productType
            tblZigbeeDeviceLinkageRelation.setEndProductType(endDevice.getProductType());
        }
        //结束ID
        tblZigbeeDeviceLinkageRelation.setEndId(endId);
        tblZigbeeDeviceLinkageRelation.setEndType(endType);
        tblZigbeeDeviceLinkageRelation.setActions(actions);
        tblZigbeeDeviceLinkageRelation.setMode(mode);

        boolean b = linkageRelationService.updateById(tblZigbeeDeviceLinkageRelation);
        if (!b) {
            return ControllerResult.toFail("修改失败");
        }
        return ControllerResult.toReturnDataSuccess("修改成功", null);
    }

    /**
     * 删除联动关系
     *
     * @param id
     * @return
     */
    @DeleteMapping("/delete")
    @CheckLogin
    public ControllerResult deleteLinkAgeSet(@NotBlank(message = "关系ID不能为空") String id, HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [deleteLinkAgeSet] -> [id:{}]", user.getAccount(), user.getOrgCode(), id);

        QueryWrapper<TblZigbeeDeviceLinkageRelation> queryWrapper = new QueryWrapper();
        queryWrapper.eq("id", id);
        TblZigbeeDeviceLinkageRelation deviceAndGatewayDo = linkageRelationService.getOne(queryWrapper);

        DeviceAndGatewayDO deviceAndGatewayDO = new DeviceAndGatewayDO();
        deviceAndGatewayDO.setZigbeeMac(deviceAndGatewayDo.getStartDeviceMac());
        String gatewayMac = gatewayService.getById(deviceAndGatewayDo.getGatewayId()).getZigbeeMac();
        deviceAndGatewayDO.setGatewayMac(gatewayMac);
        //向网关发送清除联动信息的数据帧
        Boolean aBoolean = false;
        try {
            aBoolean = linkageRelationService.linkAgeSet(deviceAndGatewayDo.getStartDeviceId(), deviceAndGatewayDo.getEndId(), deviceAndGatewayDo.getEndType(), deviceAndGatewayDo.getStartSwitchState(), null, "delete", "delete");
        } catch (NullPointerException e) {//说明设备不存在
            log.error("request -> [deleteLinkAgeSet] -> [id:{}]->设备不存在删除失败", id);
        }
        if (aBoolean) {
            boolean b = linkageRelationService.removeById(id);
            if (!b) {
                return ControllerResult.toFail("删除失败");
            }
        }
        return ControllerResult.toReturnMessageSuccess("删除成功");
    }


    /**
     * 清空联动关系
     *
     * @param startDeviceMac
     * @return
     */
    @DeleteMapping("/clear")
    @CheckLogin
    public ControllerResult clearLinkAgeSet(@NotBlank(message = "源设备MAC不能为空") String startDeviceMac, HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [clearLinkAgeSet] -> [startDeviceMac:{}]", user.getAccount(), user.getOrgCode(), startDeviceMac);

        DeviceDO deviceDO = deviceDao.selectByMac(startDeviceMac);
        if (deviceDO == null) {
            return ControllerResult.toNoDataFail("设备不存在或已被删除");
        }
        linkageRelationService.remove(Wrappers.<TblZigbeeDeviceLinkageRelation>lambdaQuery()
                .eq(TblZigbeeDeviceLinkageRelation::getStartDeviceMac, startDeviceMac));
        DeviceAndGatewayDO deviceAndGatewayDO = new DeviceAndGatewayDO();
        deviceAndGatewayDO.setZigbeeMac(deviceDO.getZigbeeMac());
        deviceAndGatewayDO.setGatewayMac(deviceDO.getGatewayMac());
        //向网关发送清除联动信息的数据帧
        String clearCmd = "1777" + "21" + "03" + "FFFFFFFFFFFFFFFFFFFFFFFF";
        String cmd = MultiFunctionSwitch0Faa8A09.getControlCmd(deviceAndGatewayDO, clearCmd);
        gatewayRedisService.writeDataToGateway(deviceAndGatewayDO.getGatewayMac(), cmd);
        log.info("result -> [clearLinkAgeSet] -> [cmd:{}]", user.getAccount(), user.getOrgCode(), cmd);
        return ControllerResult.toReturnMessageSuccess("清空成功");
    }
}
